﻿using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;

using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Linq;

namespace Utils
{
    public static partial class JsonHelper
    {
        public static readonly JsonSerializerSettings DefaultJsonSerializerSettings = new JsonSerializerSettings()
        {
            DateFormatString = "yyyy-MM-dd HH:mm:ss",
            NullValueHandling = NullValueHandling.Ignore,
            Formatting = Formatting.None,
            Converters = new List<JsonConverter>() { new LongToStringConverter() },
            FloatFormatHandling = FloatFormatHandling.Symbol,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };


        public static readonly JsonSerializer DefaultjsonSerializer = JsonSerializer.Create(DefaultJsonSerializerSettings);
        #region Json反序列化
        /// <summary>
        /// 将指定的 JSON 字符串转换为 T 类型的对象
        /// </summary>
        /// <typeparam name="T">所生成对象的类型</typeparam>
        /// <param name="str">要进行反序列化的 JSON 字符串</param>
        /// <returns>反序列化的对象</returns>
        public static T JSONDeserialize<T>(this string str, JsonSerializerSettings jsonSerializer = null)
        {
            return JsonConvert.DeserializeObject<T>(str, jsonSerializer ?? DefaultJsonSerializerSettings);
        }

        /// <summary>
        /// 将指定的 JSON 字符串转换为对象图
        /// </summary>
        /// <param name="str">要进行反序列化的 JSON 字符串</param>
        /// <returns>反序列化对象</returns>
        public static object JSONDeserialize(this string str, JsonSerializerSettings jsonSerializer = null)
        {
            return JsonConvert.DeserializeObject(str, jsonSerializer ?? DefaultJsonSerializerSettings);
        }
        #endregion

        #region Json序列化
        /// <summary>
        /// 将对象进行JSON格式序列化
        /// </summary>
        /// <param name="obj">要序列化的对象</param>
        /// <returns>JSON字符串</returns>
        public static string JSONSerialize(this object obj, JsonSerializerSettings jsonSerializer = null)
        {
            return JsonConvert.SerializeObject(obj, jsonSerializer ?? DefaultJsonSerializerSettings);
        }

        #endregion

        public static T JsonCopy<T>(this object obj)
        {
            return obj.JSONSerialize().JSONDeserialize<T>();
        }


        public static bool Contains(this JObject jToken, string value)
        {
            return jToken.ToString().Contains(value);
        }

        public static V TryValue<V>(this JToken jToken)
        {
            try
            {
                return jToken.Value<V>();
            }
            catch (Exception)
            {
                return default;
            }
        }
        public static bool TryValue<V>(this JToken jToken, out V value)
        {
            try
            {
                value = jToken.Value<V>();

                return true;
            }
            catch (Exception)
            {
                value = default;
                return false;
            }
        }
        /// <summary>
        /// json 排序
        /// </summary>
        /// <param name="jToken"></param>
        /// <returns></returns>
        public static JToken SortByKey(this JToken jToken)
        {
            if (jToken.Type == JTokenType.Object)
            {
                var jobj = new SortedDictionary<string, JToken>((JObject)jToken);
                foreach (var key in jobj.Keys.ToArray())
                {
                    jobj[key] = SortByKey(jobj[key]);
                }
                return JObject.FromObject(jobj);
            }
            else if (jToken.Type == JTokenType.Array)
            {
                List<JToken> array = new List<JToken>();
                foreach (var item in jToken)
                {
                    array.Add(SortByKey(item));
                }
                return new JArray(array.ToArray());
            }
            return jToken;
        } 
    }
}
